import os
import time
import json
import openai
import uuid
import pymysql
import datetime
import tarfile
import paramiko
import sys
import subprocess

SSH_IP = ''   # SSH服务器的IP地址
SSH_PORT = 11303            # SSH端口
SSH_USERNAME = ''    # SSH用户名
SSH_PASSWORD = '' # SSH密码
SSH_TARGET_PATH = '' #末尾的反斜杠不能丢

SSH_INFO = [
    dict(
        SSH_IP = '192.168.2.36',   # SSH服务器的IP地址
        SSH_PORT = 11303,            # SSH端口
        SSH_USERNAME = 'root',    # SSH用户名
        SSH_PASSWORD = 'iscas', # SSH密码
        SSH_TARGET_PATH = '/media/truthsource/metaapp/', #末尾的反斜杠不能丢
    ),
    dict(
        SSH_IP = '182.92.70.30',   # SSH服务器的IP地址
        SSH_PORT = 22,            # SSH端口
        SSH_USERNAME = 'root',    # SSH用户名
        SSH_PASSWORD = 'iscas0909SDS', # SSH密码
        SSH_TARGET_PATH = '/media/truthsource/metaapp/', #末尾的反斜杠不能丢
    )
]

LOCAL_PATH = os.path.dirname(__file__) + "/"

def print_progress(transferred, total):
    sys.stdout.write('\r')
    sys.stdout.write(f"Progress: {transferred}/{total} bytes [{(transferred/total)*100:.2f}%]")
    sys.stdout.flush()

# 服务器上已经存在文件时,以覆盖的方式上传新的文件    
def scp_file_transfer(source_location, target_folder_location, progress_callback, ssh_info):
    # SCP目标主机配置
    if ssh_info == None:
        scp_host = SSH_IP
        scp_user = SSH_USERNAME
        scp_password = SSH_PASSWORD
        port = SSH_PORT
    else:
        scp_host = ssh_info["SSH_IP"]  
        scp_user = ssh_info["SSH_USERNAME"]  
        scp_password = ssh_info["SSH_PASSWORD"]  
        port = ssh_info["SSH_PORT"] 
    
    try:
        # 创建SSH客户端
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        
        # 连接到SCP目标主机
        ssh.connect(scp_host, username=scp_user, password=scp_password, port=port)

        # SCP传输文件
        with paramiko.SFTPClient.from_transport(ssh.get_transport()) as sftp:
            if os.path.isdir(source_location):
                # 如果源路径是文件夹，递归传输文件夹下的所有文件
                for root, dirs, files in os.walk(source_location):
                    for file in files:
                        source_file_path = os.path.join(root, file)
                        dest_file_path = os.path.join(target_folder_location, file)
                        sftp.put(source_file_path, dest_file_path, callback=progress_callback)
            else:
                # 如果源路径是文件，直接传输文件，注意：此处的target_folder_location必须是文件的完整路径
                sftp.put(source_location, target_folder_location, callback=progress_callback)
    except Exception as e:
        print(f"Error: {e}")
    finally:
        # 关闭SSH连接
        if ssh:
            ssh.close()
          
def ssh_command(command_list):
    
    ip = SSH_IP   # SSH服务器的IP地址
    port = SSH_PORT            # SSH端口
    username = SSH_USERNAME    # SSH用户名
    password = SSH_PASSWORD # SSH密码
    
    # 创建SSH对象
    client = paramiko.SSHClient()
    
    # 自动添加策略，保存服务器的主机名和密钥信息
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    # 连接到服务器
    try:
        client.connect(ip, port=port, username=username, password=password)
    except paramiko.ssh_exception.NoValidConnectionsError:
        print("连接失败，请检查服务器IP和端口。")
        return
    except paramiko.ssh_exception.AuthenticationException:
        print("身份验证失败，请检查用户名和密码。")
        return
    
    command_str = " && ".join(command_list)
    # 执行命令
    stdin, stdout, stderr = client.exec_command(command_str)
    # 获取命令输出
    output = stdout.read().decode('utf-8')
    error = stderr.read().decode('utf-8')
    print('command_str :', command_str)
    print('output :', output)
    print('error :', error)

    # 关闭连接
    client.close()

    return output, error    

def parse_content(app_uuid, prompt_input, answer):
    
    prompt_input_json = json.loads(prompt_input)
    file_name = prompt_input_json.get("函数名称")

    #生成本地Code文件
    local_metaapp_dir_path = os.path.join(LOCAL_PATH, "Log/%s"%app_uuid)
    try:
        os.makedirs(local_metaapp_dir_path)
    except:
        pass # 目录已经存在
    code_file_path = os.path.join(local_metaapp_dir_path, file_name + ".py")
    with open(code_file_path, "wt") as wf:
        wf.write(answer)

    for ssh_dict in SSH_INFO:
        
        global SSH_IP, SSH_PORT, SSH_USERNAME, SSH_PASSWORD, SSH_TARGET_PATH
        SSH_IP = ssh_dict['SSH_IP']
        SSH_PORT = ssh_dict['SSH_PORT']
        SSH_USERNAME = ssh_dict['SSH_USERNAME']
        SSH_PASSWORD = ssh_dict['SSH_PASSWORD']
        SSH_TARGET_PATH = ssh_dict['SSH_TARGET_PATH']

        #SSH传输到远端服务器
        remote_path = os.path.join(SSH_TARGET_PATH, '%s/'%app_uuid) # metaapp 对应的文件夹路径
        command_list = ['cd %s' % remote_path, 'mkdir Code'] # metaapp 下创建 Code 文件夹

        ssh_command(command_list)
        remote_path_code = os.path.join(remote_path, 'Code/')
        code_file_path_target = os.path.join(remote_path_code, os.path.basename(code_file_path))
        scp_file_transfer(code_file_path, code_file_path_target, print_progress, None)

        remote_path_code = os.path.join(remote_path, 'sourceCode/PYTHON/')
        code_file_path_target = os.path.join(remote_path_code, os.path.basename(code_file_path))
        scp_file_transfer(code_file_path, code_file_path_target, print_progress, None)

    return code_file_path_target       

def scp_download(remote_path, local_path):
    for ssh_dict in SSH_INFO:
        
        global SSH_IP, SSH_PORT, SSH_USERNAME, SSH_PASSWORD, SSH_TARGET_PATH
        SSH_IP = ssh_dict['SSH_IP']
        SSH_PORT = ssh_dict['SSH_PORT']
        SSH_USERNAME = ssh_dict['SSH_USERNAME']
        SSH_PASSWORD = ssh_dict['SSH_PASSWORD']
        SSH_TARGET_PATH = ssh_dict['SSH_TARGET_PATH']
        
        # SCP目标主机配置
        scp_host = SSH_IP  # 替换为你的SSH IP
        scp_user = SSH_USERNAME  # 替换为你的SSH用户名
        scp_password = SSH_PASSWORD  # 替换为你的SSH密码
        port = SSH_PORT  # 替换为你的SSH端口

        ssh = None

        try:
            # 创建SSH客户端
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

            # 连接到SCP目标主机
            ssh.connect(scp_host, username=scp_user, password=scp_password, port=port)

            # 创建SFTP客户端
            with ssh.open_sftp() as sftp:
                if sftp.stat(remote_path).st_mode & 0o40000:  # 检查是否是目录
                    # 如果是目录，递归下载目录下的所有文件
                    download_directory(sftp, remote_path, local_path, print_progress)
                else:
                    # 如果是文件，直接下载文件
                    sftp.get(remote_path, local_path, callback=print_progress)
        except Exception as e:
            print(f"Error: {e}")
        finally:
            # 关闭SSH连接
            if ssh:
                ssh.close()

def download_directory(sftp, remote_path, local_path):
    os.makedirs(local_path, exist_ok=True)
    for item in sftp.listdir_attr(remote_path):
        remote_item_path = os.path.join(remote_path, item.filename).replace('\\', '/')
        local_item_path = os.path.join(local_path, item.filename)
        if item.st_mode & 0o40000:  # 检查是否是目录
            download_directory(sftp, remote_item_path, local_item_path, progress_callback)
        else:
            sftp.get(remote_item_path, local_item_path, callback=progress_callback)

def print_progress(transferred, total):
    sys.stdout.write('\r')
    sys.stdout.write(f"Progress: {transferred}/{total} bytes [{(transferred/total)*100:.2f}%]")
    sys.stdout.flush()

if __name__ == '__main__':
    pass